//*******************************************************************************************************
// Source: http://www.vbaccelerator.com/home/NET/Code/Libraries/Shell_Projects/SysImageList/article.asp *
//*******************************************************************************************************
using System;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;

namespace Bookvar.Common
{

	#region Public Enumerations

	/// <summary>
	/// Available system image list sizes
	/// </summary>
	public enum SysImageListSize : int
	{
		/// <summary>
		/// System Large Icon Size (typically 32x32)
		/// </summary>
		LargeIcons = 0x0,
		/// <summary>
		/// System Small Icon Size (typically 16x16)
		/// </summary>
		SmallIcons = 0x1,
		/// <summary>
		/// System Extra Large Icon Size (typically 48x48).
		/// Only available under XP; under other OS the
		/// Large Icon ImageList is returned.
		/// </summary>
		ExtraLargeIcons = 0x2
	}

	/// <summary>
	/// Flags controlling how the Image List item is 
	/// drawn
	/// </summary>
	[Flags]
	public enum ImageListDrawItemConstants : int
	{
		/// <summary>
		/// Draw item normally.
		/// </summary>
		None = 0x0,
		/// <summary>
		/// Draw item transparently.
		/// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ild")]
        IldTransparent = 0x1,
		/// <summary>
		/// Draw item blended with 25% of the specified foreground colour
		/// or the Highlight colour if no foreground colour specified.
		/// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ild")]
        IldBlend25 = 0x2,
		/// <summary>
		/// Draw item blended with 50% of the specified foreground colour
		/// or the Highlight colour if no foreground colour specified.
		/// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ild")]
        IldSelected = 0x4,
		/// <summary>
		/// Draw the icon's mask
		/// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ild")]
        IldMask = 0x10,
		/// <summary>
		/// Draw the icon image without using the mask
		/// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ild")]
        IldImage = 0x20,
		/// <summary>
		/// Draw the icon using the ROP specified.
		/// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ild")]
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Rop")]
        IldRop = 0x40,
		/// <summary>
		/// Preserves the alpha channel in dest. XP only.
		/// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ild")]
        IldPreserveAlpha = 0x1000,
		/// <summary>
		/// Scale the image to cx, cy instead of clipping it.  XP only.
		/// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ild")]
        IldScale = 0x2000,
		/// <summary>
		/// Scale the image to the current DPI of the display. XP only.
		/// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ild")]
        IldDpiScale = 0x4000
	}

	/// <summary>
	/// Enumeration containing XP ImageList Draw State options
	/// </summary>
	[Flags]
	public enum ImageListDrawStateConstants : int
	{
		/// <summary>
		/// The image state is not modified. 
		/// </summary>
		None = (0x00000000),
		/// <summary>
		/// Adds a glow effect to the icon, which causes the icon to appear to glow 
		/// with a given color around the edges. (Note: does not appear to be
		/// implemented)
		/// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ils")]
        IlsGlow = (0x00000001),
		//The color for the glow effect is passed to the IImageList::Draw method in the crEffect member of IMAGELISTDRAWPARAMS. 
		/// <summary>
		/// Adds a drop shadow effect to the icon. (Note: does not appear to be
		/// implemented)
		/// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ils")]
        IlsShadow = (0x00000002),
		//The color for the drop shadow effect is passed to the IImageList::Draw method in the crEffect member of IMAGELISTDRAWPARAMS. 
		/// <summary>
		/// Saturates the icon by increasing each color component 
		/// of the RGB triplet for each pixel in the icon. (Note: only ever appears
		/// to result in a completely unsaturated icon)
		/// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ils")]
        IlsSaturate = (0x00000004),
		// The amount to increase is indicated by the frame member in the IMAGELISTDRAWPARAMS method. 
		/// <summary>
		/// Alpha blends the icon. Alpha blending controls the transparency 
		/// level of an icon, according to the value of its alpha channel. 
		/// (Note: does not appear to be implemented).
		/// </summary>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "Ils")]
        IlsAlpha = (0x00000008)
		//The value of the alpha channel is indicated by the frame member in the IMAGELISTDRAWPARAMS method. The alpha channel can be from 0 to 255, with 0 being completely transparent, and 255 being completely opaque. 
	}

	/// <summary>
	/// Flags specifying the state of the icon to draw from the Shell
	/// </summary>
	[Flags]
	public enum ShellIconStateConstants
	{
		/// <summary>
		/// Get icon in normal state
		/// </summary>
		None = 0,
		/// <summary>
		/// Put a link overlay on icon 
		/// </summary>
		ShellIconStateLinkOverlay = 0x8000,
		/// <summary>
		/// show icon in selected state 
		/// </summary>
		ShellIconStateSelected = 0x10000,
		/// <summary>
		/// get open icon 
		/// </summary>
		ShellIconStateOpen = 0x2,
		/// <summary>
		/// apply the appropriate overlays
		/// </summary>
		ShellIconAddOverlays = 0x000000020,
	}

	#endregion

	#region SysImageList

	/// <summary>
	/// Summary description for SysImageList.
	/// </summary>
	public class SysImageList : IDisposable
	{
		#region UnmanagedCode

		private const int MaxPath = 260;

		

		//[DllImport( "user32.dll" )]
		//private static extern int DestroyIcon( IntPtr hIcon );

		private const int FileAttributeNormal = 0x80;
		private const int FileAttributeDirectory = 0x10;

		private const int FormatMessageALLOCATE_BUFFER = 0x100;
		private const int FormatMessageARGUMENT_ARRAY = 0x2000;
		private const int FormatMessageFROM_HMODULE = 0x800;
		private const int FormatMessageFROM_STRING = 0x400;
		private const int FormatMessageFROM_SYSTEM = 0x1000;
		private const int FormatMessageIGNORE_INSERTS = 0x200;
		private const int FormatMessageMAX_WIDTH_MASK = 0xFF;

		//[DllImport("kernel32")]
		//private static extern int FormatMessage(
		//    int dwFlags,
		//    IntPtr lpSource,
		//    int dwMessageId,
		//    int dwLanguageId,
		//    string lpBuffer,
		//    uint nSize,
		//    int argumentsLong);

		//[DllImport("kernel32")]
		//private static extern int GetLastError();

		//[DllImport("comctl32")]
		//private static extern int ImageList_Draw(
		//    IntPtr hIml,
		//    int i,
		//    IntPtr hdcDst,
		//    int x,
		//    int y,
		//    int fStyle);

		//[DllImport("comctl32")]
		//private static extern int ImageList_DrawIndirect(
		//    ref IMAGELISTDRAWPARAMS pimldp);

		


		/// <summary>
		/// SHGetImageList is not exported correctly in XP.  See KB316931
		/// http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q316931
		/// Apparently (and hopefully) ordinal 727 isn't going to change.
		/// </summary>

		#endregion

		#region Private Enumerations

		[Flags]
		private enum SHGetFileInfoConstants : int
		{
			SHGFI_ICON = 0x100, // get icon 
			SHGFI_DISPLAYNAME = 0x200, // get display name 
			SHGFI_TYPENAME = 0x400, // get type name 
			SHGFI_ATTRIBUTES = 0x800, // get attributes 
			SHGFI_ICONLOCATION = 0x1000, // get icon location 
			SHGFI_EXETYPE = 0x2000, // return exe type 
			SHGFI_SYSICONINDEX = 0x4000, // get system icon index 
			SHGFI_LINKOVERLAY = 0x8000, // put a link overlay on icon 
			SHGFI_SELECTED = 0x10000, // show icon in selected state 
			SHGFI_ATTR_SPECIFIED = 0x20000, // get only specified attributes 
			SHGFI_LARGEICON = 0x0, // get large icon 
			SHGFI_SMALLICON = 0x1, // get small icon 
			SHGFI_OPENICON = 0x2, // get open icon 
			SHGFI_SHELLICONSIZE = 0x4, // get shell size icon 
			//SHGFI_PIDL = 0x8,                  // pszPath is a pidl 
			SHGFI_USEFILEATTRIBUTES = 0x10, // use passed dwFileAttribute 
			SHGFI_ADDOVERLAYS = 0x000000020, // apply the appropriate overlays
			SHGFI_OVERLAYINDEX = 0x000000040 // Get the index of the overlay
		}

		#endregion

		#region Private ImageList structures


		#endregion

		#region Private ImageList COM Interop (XP)

		#endregion

		#region Member Variables

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Reliability", "CA2006:UseSafeHandleToEncapsulateNativeResources")]
        private IntPtr hIml = IntPtr.Zero;
		private Bookvar.Common.NativeMethods.IImageList iImageList;
		private SysImageListSize size = SysImageListSize.SmallIcons;
		private bool disposed;

		#endregion

		#region Implementation

		#region Properties

		/// <summary>
		/// Gets the hImageList handle
		/// </summary>
		public IntPtr Handle
		{
			get { return hIml; }
		}

		/// <summary>
		/// Gets/sets the size of System Image List to retrieve.
		/// </summary>
		public SysImageListSize ImageListSize
		{
			get { return size; }
			set
			{
				size = value;
				create();
			}
		}

		///// <summary>
		///// Returns the size of the Image List Icons.
		///// </summary>
		//public Size Size
		//{
		//    get
		//    {
		//        int cx = 0;
		//        int cy = 0;
		//        if (iImageList == null)
		//        {
		//            ImageList_GetIconSize(
		//                hIml,
		//                ref cx,
		//                ref cy);
		//        }
		//        else
		//        {
		//            iImageList.GetIconSize(ref cx, ref cy);
		//        }
		//        Size sz = new Size(
		//            cx, cy);
		//        return sz;
		//    }
		//}

		#endregion

		#region Methods

		/// <summary>
		/// Returns a GDI+ copy of the icon from the ImageList
		/// at the specified index.
		/// </summary>
		/// <param name="index">The index to get the icon for</param>
		/// <returns>The specified icon</returns>
		public Icon Icon(int index)
		{
			Icon icon = null;

			IntPtr hIcon = IntPtr.Zero;
			if (iImageList == null)
			{
				hIcon = NativeMethods.ImageListGetIcon(
					hIml,
					index,
					(int) ImageListDrawItemConstants.IldTransparent);
			}
			else
			{
				int result = iImageList.GetIcon(
					index,
					(int) ImageListDrawItemConstants.IldTransparent,
					ref hIcon);
				if (result == 0)
				{
				}
			}

			if (hIcon != IntPtr.Zero)
			{
				icon = System.Drawing.Icon.FromHandle(hIcon);
			}
			return icon;
		}

		/// <summary>
		/// Return the index of the icon for the specified file, always using 
		/// the cached version where possible.
		/// </summary>
		/// <param name="fileName">Filename to get icon for</param>
		/// <returns>Index of the icon</returns>
		public int IconIndex(string fileName)
		{
			return IconIndex(fileName, false);
		}

		/// <summary>
		/// Returns the index of the icon for the specified file
		/// </summary>
		/// <param name="fileName">Filename to get icon for</param>
		/// <param name="forceLoadFromDisk">If True, then hit the disk to get the icon,
		/// otherwise only hit the disk if no cached icon is available.</param>
		/// <returns>Index of the icon</returns>
		public int IconIndex(
			string fileName,
			bool forceLoadFromDisk)
		{
			return IconIndex(
				fileName,
				forceLoadFromDisk,
				ShellIconStateConstants.None);
		}

		/// <summary>
		/// Returns the index of the icon for the specified file
		/// </summary>
		/// <param name="fileName">Filename to get icon for</param>
		/// <param name="forceLoadFromDisk">If True, then hit the disk to get the icon,
		/// otherwise only hit the disk if no cached icon is available.</param>
		/// <param name="iconState">Flags specifying the state of the icon
		/// returned.</param>
		/// <returns>Index of the icon</returns>
		public int IconIndex(
			string fileName,
			bool forceLoadFromDisk,
			ShellIconStateConstants iconState
			)
		{
			SHGetFileInfoConstants dwFlags = SHGetFileInfoConstants.SHGFI_SYSICONINDEX;
			int dwAttr = 0;
			if (size == SysImageListSize.SmallIcons)
			{
				dwFlags |= SHGetFileInfoConstants.SHGFI_SMALLICON;
			}

			// We can choose whether to access the disk or not. If you don't
			// hit the disk, you may get the wrong icon if the icon is
			// not cached. Also only works for files.
			if (!forceLoadFromDisk)
			{
				dwFlags |= SHGetFileInfoConstants.SHGFI_USEFILEATTRIBUTES;
				dwAttr = FileAttributeNormal;
			}
			else
			{
				dwAttr = 0;
			}

			// sFileSpec can be any file. You can specify a
			// file that does not exist and still get the
			// icon, for example sFileSpec = "C:\PANTS.DOC"
			Bookvar.Common.NativeMethods.SHFILEINFO shfi = new Bookvar.Common.NativeMethods.SHFILEINFO();
			uint shfiSize = (uint) Marshal.SizeOf(shfi.GetType());
			IntPtr retVal = NativeMethods. SHGetFileInfo(
				fileName, dwAttr, ref shfi, shfiSize,
				((uint) (dwFlags) | (uint) iconState));

			if (retVal.Equals(IntPtr.Zero))
			{
				Debug.Assert((!retVal.Equals(IntPtr.Zero)), "Failed to get icon index");
				return 0;
			}
			else
			{
				return shfi.iIcon;
			}
		}

		///// <summary>
		///// Draws an image
		///// </summary>
		///// <param name="hdc">Device context to draw to</param>
		///// <param name="index">Index of image to draw</param>
		///// <param name="x">X Position to draw at</param>
		///// <param name="y">Y Position to draw at</param>
		//public void DrawImage(
		//    IntPtr hdc,
		//    int index,
		//    int x,
		//    int y
		//    )
		//{
		//    DrawImage(hdc, index, x, y, ImageListDrawItemConstants.IldTransparent);
		//}

		///// <summary>
		///// Draws an image using the specified flags
		///// </summary>
		///// <param name="hdc">Device context to draw to</param>
		///// <param name="index">Index of image to draw</param>
		///// <param name="x">X Position to draw at</param>
		///// <param name="y">Y Position to draw at</param>
		///// <param name="flags">Drawing flags</param>
		//public void DrawImage(
		//    IntPtr hdc,
		//    int index,
		//    int x,
		//    int y,
		//    ImageListDrawItemConstants flags
		//    )
		//{
		//    int result;
		//    if (iImageList == null)
		//    {
		//        result = ImageList_Draw(
		//           hIml,
		//           index,
		//           hdc,
		//           x,
		//           y,
		//           (int) flags);
		//    }
		//    else
		//    {
		//        IMAGELISTDRAWPARAMS pimldp = new IMAGELISTDRAWPARAMS();
		//        pimldp.hdcDst = hdc;
		//        pimldp.cbSize = Marshal.SizeOf(pimldp.GetType());
		//        pimldp.i = index;
		//        pimldp.x = x;
		//        pimldp.y = y;
		//        pimldp.rgbFg = -1;
		//        pimldp.fStyle = (int) flags;
		//        result = iImageList.Draw(ref pimldp);
		//    }
		//    if (result == 0)
		//    {
		//    }
		//}

		///// <summary>
		///// Draws an image using the specified flags and specifies
		///// the size to clip to (or to stretch to if IldSCALE
		///// is provided).
		///// </summary>
		///// <param name="hdc">Device context to draw to</param>
		///// <param name="index">Index of image to draw</param>
		///// <param name="x">X Position to draw at</param>
		///// <param name="y">Y Position to draw at</param>
		///// <param name="flags">Drawing flags</param>
		///// <param name="cx">Width to draw</param>
		///// <param name="cy">Height to draw</param>
		//public void DrawImage(
		//    IntPtr hdc,
		//    int index,
		//    int x,
		//    int y,
		//    ImageListDrawItemConstants flags,
		//    int cx,
		//    int cy
		//    )
		//{
		//    IMAGELISTDRAWPARAMS pimldp = new IMAGELISTDRAWPARAMS();
		//    pimldp.hdcDst = hdc;
		//    pimldp.cbSize = Marshal.SizeOf(pimldp.GetType());
		//    pimldp.i = index;
		//    pimldp.x = x;
		//    pimldp.y = y;
		//    pimldp.cx = cx;
		//    pimldp.cy = cy;
		//    pimldp.fStyle = (int) flags;
		//    int result ; 
		//    if (iImageList == null)
		//    {
		//        pimldp.himl = hIml;
		//        result = ImageList_DrawIndirect(ref pimldp);
		//    }
		//    else
		//    {
		//        result = iImageList.Draw(ref pimldp);
		//    }
		//    if(result == 0)
		//    {
		//    }
		//}

		///// <summary>
		///// Draws an image using the specified flags and state on XP systems.
		///// </summary>
		///// <param name="hdc">Device context to draw to</param>
		///// <param name="index">Index of image to draw</param>
		///// <param name="x">X Position to draw at</param>
		///// <param name="y">Y Position to draw at</param>
		///// <param name="flags">Drawing flags</param>
		///// <param name="cx">Width to draw</param>
		///// <param name="cy">Height to draw</param>
		///// <param name="foreColor">Fore colour to blend with when using the 
		///// IldSELECTED or IldBLEND25 flags</param>
		///// <param name="stateFlags">State flags</param>
		///// <param name="glowOrShadowColor">If stateFlags include IlsGLOW, then
		///// the colour to use for the glow effect.  Otherwise if stateFlags includes 
		///// IlsSHADOW, then the colour to use for the shadow.</param>
		///// <param name="saturateColorOrAlpha">If stateFlags includes IlsALPHA,
		///// then the alpha component is applied to the icon. Otherwise if 
		///// IlsSATURATE is included, then the (R,G,B) components are used
		///// to saturate the image.</param>
		//public void DrawImage(
		//    IntPtr hdc,
		//    int index,
		//    int x,
		//    int y,
		//    ImageListDrawItemConstants flags,
		//    int cx,
		//    int cy,
		//    Color foreColor,
		//    ImageListDrawStateConstants stateFlags,
		//    Color saturateColorOrAlpha,
		//    Color glowOrShadowColor
		//    )
		//{
		//    IMAGELISTDRAWPARAMS pimldp = new IMAGELISTDRAWPARAMS();
		//    pimldp.hdcDst = hdc;
		//    pimldp.cbSize = Marshal.SizeOf(pimldp.GetType());
		//    pimldp.i = index;
		//    pimldp.x = x;
		//    pimldp.y = y;
		//    pimldp.cx = cx;
		//    pimldp.cy = cy;
		//    pimldp.rgbFg = Color.FromArgb(0,
		//                                   foreColor.R, foreColor.G, foreColor.B).ToArgb();
		//    Console.WriteLine("{0}", pimldp.rgbFg);
		//    pimldp.fStyle = (int) flags;
		//    pimldp.fState = (int) stateFlags;
		//    if ((stateFlags & ImageListDrawStateConstants.IlsAlpha) ==
		//         ImageListDrawStateConstants.IlsAlpha)
		//    {
		//        // Set the alpha:
		//        pimldp.Frame = (int) saturateColorOrAlpha.A;
		//    }
		//    else if ((stateFlags & ImageListDrawStateConstants.IlsSaturate) ==
		//              ImageListDrawStateConstants.IlsSaturate)
		//    {
		//        // discard alpha channel:
		//        saturateColorOrAlpha = Color.FromArgb(0,
		//                                               saturateColorOrAlpha.R,
		//                                               saturateColorOrAlpha.G,
		//                                               saturateColorOrAlpha.B);
		//        // set the saturate color
		//        pimldp.Frame = saturateColorOrAlpha.ToArgb();
		//    }
		//    glowOrShadowColor = Color.FromArgb(0,
		//                                        glowOrShadowColor.R,
		//                                        glowOrShadowColor.G,
		//                                        glowOrShadowColor.B);
		//    pimldp.crEffect = glowOrShadowColor.ToArgb();
		//    if (iImageList == null)
		//    {
		//        pimldp.himl = hIml;
		//        int ret = ImageList_DrawIndirect(ref pimldp);
		//    }
		//    else
		//    {
		//        iImageList.Draw(ref pimldp);
		//    }
		//}

		/// <summary>
		/// Determines if the system is running Windows XP
		/// or above
		/// </summary>
		/// <returns>True if system is running XP or above, False otherwise</returns>
		private static bool IsXpOrAbove()
		{
			bool ret = false;
			if (Environment.OSVersion.Version.Major > 5)
			{
				ret = true;
			}
			else if ((Environment.OSVersion.Version.Major == 5) &&
					  (Environment.OSVersion.Version.Minor >= 1))
			{
				ret = true;
			}
			return ret;
			//return false;
		}

		/// <summary>
		/// Creates the SystemImageList
		/// </summary>
		private void create()
		{
			// forget last image list if any:
			hIml = IntPtr.Zero;

			if (IsXpOrAbove())
			{
				// Get the System IImageList object from the Shell:
				Guid iidImageList = new Guid("46EB5926-582E-4017-9FDF-E8998DAA0950");
				int ret = NativeMethods.SHGetImageList(
					(int) size,
					ref iidImageList,
					ref iImageList
					);
				// the image list handle is the IUnknown pointer, but 
				// using Marshal.GetIUnknownForObject doesn't return
				// the right value.  It really doesn't hurt to make
				// a second call to get the handle:
				int result = NativeMethods.SHGetImageListHandle((int) size, ref iidImageList, ref hIml);
				if (result == 0 || ret == 0)
				{
				}
			}
			else
			{
				// Prepare flags:
				SHGetFileInfoConstants dwFlags = SHGetFileInfoConstants.SHGFI_USEFILEATTRIBUTES |
												 SHGetFileInfoConstants.SHGFI_SYSICONINDEX;
				if (size == SysImageListSize.SmallIcons)
				{
					dwFlags |= SHGetFileInfoConstants.SHGFI_SMALLICON;
				}
				// Get image list
				Bookvar.Common.NativeMethods.SHFILEINFO shfi = new Bookvar.Common.NativeMethods.SHFILEINFO();
				uint shfiSize = (uint) Marshal.SizeOf(shfi.GetType());

				// Call SHGetFileInfo to get the image list handle
				// using an arbitrary file:
				hIml = NativeMethods.SHGetFileInfo(
					".txt",
					FileAttributeNormal,
					ref shfi,
					shfiSize,
					(uint) dwFlags);
				Debug.Assert((hIml != IntPtr.Zero), "Failed to create Image List");
			}
		}

		#endregion

		#region Constructor, Dispose, Destructor

		/// <summary>
		/// Creates a Small Icons SystemImageList 
		/// </summary>
		public SysImageList()
		{
			create();
		}

		/// <summary>
		/// Creates a SystemImageList with the specified size
		/// </summary>
		/// <param name="size">Size of System ImageList</param>
		public SysImageList(SysImageListSize size)
		{
			this.size = size;
			create();
		}

		/// <summary>
		/// Clears up any resources associated with the SystemImageList
		/// </summary>
		public void Dispose()
		{
			Dispose(true);
			GC.SuppressFinalize(this);
		}

		/// <summary>
		/// Clears up any resources associated with the SystemImageList
		/// when disposing is true.
		/// </summary>
		/// <param name="disposing">Whether the object is being disposed</param>
		protected virtual void Dispose(bool disposing)
		{
			if (!disposed)
			{
				if (disposing)
				{
					if (iImageList != null)
					{
						Marshal.ReleaseComObject(iImageList);
					}
					iImageList = null;
				}
			}
			disposed = true;
		}

		/// <summary>
		/// Finalise for SysImageList
		/// </summary>
		~SysImageList()
		{
			Dispose(false);
		}
	}

		#endregion

		#endregion

	#endregion
}